package abstracts;

import java.awt.Graphics;
import tools.FrameLimit;
import tools.GameApplet;

/** Any screen, loading screen, menu screen, statistics screen, etc. */
public abstract class Screen implements Runnable {
    /** */
    public static final int FPS = 60;

    /**
     * The {@linkplain GameApplet} which this screen is to be
     * displayed in.
     */
    private final GameApplet applet;
    /** */
    private final FrameLimit limit;

    /**
     * @param gameApplet - the {@link GameApplet} which this screen is
     *            to be displayed in.
     */
    public Screen(final GameApplet gameApplet) {
        applet = gameApplet;
        limit = new FrameLimit(FPS);
    }

    /** @return the width of the screen in pixels. */
    public abstract int getWidth();

    /** @return the height of the screen in pixels. */
    public abstract int getHeight();

    /** @return fps. */
    public final int getCurrentFps() {
        return limit.getCurrentFps();
    }

    /** @return the applet which this screen is attached to */
    public final GameApplet getApplet() {
        return applet;
    }

    /**
     * Called by the {@linkplain GameApplet} when the screen is
     * entered.
     */
    public final void run() {
        begin();
        limit.begin();
        while (applet.getScreen() == this) {
            applet.draw(this);
            step();
            limit.step();
        }
        end();
    }

    /**
     * Called once when the screen begins. Use this for any resource
     * allocation.
     */
    public synchronized void begin() {
        // Do nothing
    }

    /**
     * Called once when the screen ends. Use this for any resource
     * cleaning.
     */
    public synchronized void end() {
        // Do nothing
    }

    /**
     * Called repetitively until the screen is ended. It's a good idea
     * to have a call to {@code Thread.sleep()} in here somewhere so
     * that you don't hog the processor.
     */
    public synchronized void step() {
        // Do nothing
    }

    /**
     * Called by the {@linkplain GameApplet} shortly after a call to
     * {@code redraw()} or immediately after a call to {@code
     * redrawNow()}.
     * 
     * @param g - a {@linkplain Graphics} object to draw the screen
     *            to.
     */
    public synchronized void draw(final Graphics g) {
        // Do nothing
    }
}
